#ifndef OMG_DDS_CORE_DURATION_HPP_
#define OMG_DDS_CORE_DURATION_HPP_

/* Copyright (c) 2009-2010, Real-Time Innovations, Inc.
 * Copyright (c) 2010, Object Management Group, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - Neither the names of the above copyright holders nor the names of their
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL A COPYRIGHT HOLDER OR CONTRIBUTOR BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

namespace dds { namespace core {

/**
 * This class represents a time interval.
 */
class Duration /* : public dds::core::Value */ {
public:
    static const Duration zero();          // {0, 0}
    static const Duration infinite();      // {0x7fffffff, 0x7fffffff}
public:
    OMG_DDS_VALUE_TYPE(Duration)

    /**
     * Create a duration elapsing a specific amount of time.
     */
    explicit Duration(int32_t sec, uint32_t nanosec = 0);

public:
    static const Duration from_microseconds(int64_t microseconds);
    static const Duration from_milliseconds(int64_t milliseconds);
    static const Duration from_seconds(double seconds);
    
public:
    int32_t sec() const;
    void    sec(int32_t s);

    uint32_t nanosec() const;
    void     nanosec(uint32_t ns);

    /**
     * Reset the interval for this Duration.
     *
     * @param s second
     * @param ns nanosecont
     */
    void reset(int32_t s, uint32_t ns);

public:
    int compare(const Duration& that) const;

    bool operator >(const Duration& that) const;
    bool operator >=(const Duration& that) const;

    bool operator <=(const Duration& that) const;
    bool operator <(const Duration& that) const;

public:
    Duration& operator+=(const Duration &a_ti);
    Duration& operator-=(const Duration &a_ti);

public:
    void set_in_milliseconds(int64_t millisec);
    int64_t get_in_milliseconds() const;
    
    void set_in_microseconds(int64_t microsec);
    int64_t get_in_microseconds() const;
    
    void set_in_seconds(double seconds);
    double get_in_seconds() const;
    
private:
    uint32_t sec_;
    uint32_t nsec_;
};

// Duration arithmetic operators.
const Duration operator +(const Duration& lhs,
                          const Duration& rhs);
const Duration operator -(const Duration& lhs,
                          const Duration& rhs);
const Duration operator *(uint32_t lhs,
                          const Duration& rhs);
const Duration operator *(const Duration& lhs,
                          uint32_t rhs);
const Duration operator /(uint32_t lhs,
                          const Duration& rhs);
const Duration operator /(const Duration& lhs,
                          uint32_t rhs);
        
} } /* namespace dds / namespace core  */
#endif /* OMG_DDS_CORE_DURATION_HPP_ */

